package jnpf.util;


import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import jnpf.model.common.ModuleData;
import jnpf.model.ragFlow.common.RagFlowApiResult;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 返回模型内容和DO内容的解析工具
 * 提供Markdown解析、树形结构构建、扁平化处理和Unicode解码功能
 */
public class ResultHandleUtil {

    private static final ObjectMapper objectMapper = new ObjectMapper();

    public static <T> RagFlowApiResult<T> txtConvertObj(String jsonResponse, Class<T> valueType) throws Exception {
        try {
            if (jsonResponse == null) {
                return null;
            }
            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            return objectMapper.readValue(jsonResponse,
                objectMapper.getTypeFactory().constructParametricType(RagFlowApiResult.class, valueType));
        } catch (Exception e) {
            throw new Exception("返回json转换对象失败 " + e.getMessage());
        }
    }

    public static <T> RagFlowApiResult<List<T>> txtConvertObjForList(String jsonResponse, Class<T> elementType) throws Exception {
        try {
            JavaType listType = objectMapper.getTypeFactory().constructParametricType(List.class, elementType);
            JavaType resultType = objectMapper.getTypeFactory().constructParametricType(RagFlowApiResult.class, listType);
            return objectMapper.readValue(jsonResponse, resultType);
        } catch (Exception e) {
            throw new Exception("返回json转换对象失败 " + e.getMessage());
        }
    }


    /**
     * 将Markdown格式文本解析为ModuleData列表
     * 支持多级标题结构，使用#数量表示层级
     * 示例输入:
     * # 1 一级标题
     * ## 1.1 二级标题
     *
     * @param thought 包含Markdown格式的字符串
     * @return 解析后的ModuleData节点列表
     */
    public static List<ModuleData> parseMarkdownList(String thought) {
        List<ModuleData> nodes = new ArrayList<>();
        String[] lines = thought.split("\n");

        for (String line : lines) {
            line = line.trim();
            if (line.isEmpty()) {
                continue;
            }

            // 解析标题层级(由#的数量决定)
            int level = 0;
            while (line.startsWith("#")) {
                level++;
                line = line.substring(1).trim();
            }

            // 解析ID和名称(格式: ID 名称)
            String[] parts = line.split(" ", 2);
            if (parts.length < 2) {
                continue;
            }
            String id = parts[0];
            String name = parts[1];

            // 创建节点并设置基本属性
            ModuleData node = new ModuleData();
            node.setId(id);
            node.setName(id + " " + name);
            node.setLevel(String.valueOf(level));

            // 设置父节点ID
            if (level == 1) {
                node.setPid("0"); // 一级节点的父节点为根节点
            } else {
                ModuleData parent = findParent(nodes, level - 1);
                if (parent != null) {
                    node.setPid(parent.getId());
                }
            }

            nodes.add(node);
        }
        return nodes;
    }

    /**
     * 查找指定层级的最近父节点
     *
     * @param nodes       已解析的节点列表
     * @param targetLevel 目标父节点层级
     * @return 找到的父节点，未找到时返回null
     */
    private static ModuleData findParent(List<ModuleData> nodes, int targetLevel) {
        // 从后往前查找最近的父节点
        for (int i = nodes.size() - 1; i >= 0; i--) {
            ModuleData node = nodes.get(i);
            if (Integer.parseInt(node.getLevel()) == targetLevel) {
                return node;
            }
        }
        return null;
    }

    /**
     * 将扁平节点列表转换为树形结构
     *
     * @param flatNodes 扁平节点列表
     * @return 树形结构的节点列表
     */
    public static List<ModuleData> buildTree(List<ModuleData> flatNodes) {
        List<ModuleData> treeNodes = new ArrayList<>();

        for (ModuleData node : flatNodes) {
            if ("0".equals(node.getPid())) {
                // 根节点直接添加到树中
                treeNodes.add(node);
            } else {
                // 非根节点查找并添加到父节点的子列表中
                for (ModuleData parent : flatNodes) {
                    if (node.getPid().equals(parent.getId())) {
                        parent.getChildren().add(node);
                        break;
                    }
                }
            }
        }
        return treeNodes;
    }

    /**
     * 打印树形结构(调试用)
     *
     * @param nodes 当前层级的节点列表
     * @param level 当前层级深度(用于缩进)
     */
    public static void printTree(List<ModuleData> nodes, int level) {
        for (ModuleData node : nodes) {
            // 根据层级打印缩进
            for (int i = 0; i < level; i++) {
                System.out.print("  ");
            }
            System.out.println(node.getName());

            // 递归打印子节点
            printTree(node.getChildren(), level + 1);
        }
    }

    /**
     * 将树形结构转换为扁平列表(广度优先)
     *
     * @param root 根节点
     * @return 扁平节点列表
     */
    public static List<ModuleData> flattenTree(ModuleData root) {
        List<ModuleData> flatList = new ArrayList<>();
        flattenTreeRecursive(root, flatList);
        return flatList;
    }

    /**
     * 递归处理树形结构，将节点添加到扁平列表
     * 采用深拷贝避免修改原始节点
     *
     * @param node     当前处理的节点
     * @param flatList 目标扁平列表
     */
    private static void flattenTreeRecursive(ModuleData node, List<ModuleData> flatList) {
        // 克隆当前节点，避免修改原节点的children
        ModuleData clonedNode = new ModuleData();
        clonedNode.setId(node.getId());
        clonedNode.setName(node.getName());
        clonedNode.setPid(node.getPid());
        clonedNode.setLevel(node.getLevel());

        // 将克隆的节点添加到列表中
        flatList.add(clonedNode);

        // 递归处理子节点
        if (node.getChildren() != null) {
            for (ModuleData child : node.getChildren()) {
                flattenTreeRecursive(child, flatList);
            }
        }
    }

    /**
     * 将Unicode编码的字符串转换为中文
     * 示例输入: "\u4e2d\u6587" -> 输出: "中文"
     *
     * @param input 包含Unicode编码的字符串
     * @return 解码后的字符串
     */
    public static String decodeUnicode(String input) {
        if (input == null || input.isEmpty()) {
            return "";
        }
        Pattern pattern = Pattern.compile("\\\\u([0-9a-fA-F]{4})");
        Matcher matcher = pattern.matcher(input);
        StringBuffer sb = new StringBuffer(input.length());

        // 替换所有Unicode编码为对应字符
        while (matcher.find()) {
            String group = matcher.group(1);
            char ch = (char) Integer.parseInt(group, 16);
            matcher.appendReplacement(sb, Character.toString(ch));
        }
        matcher.appendTail(sb);

        return sb.toString();
    }

    /**
     * 将JSON字符串转换为Java对象
     * @param jsonStr JSON字符串
     * @param valueType 目标对象类型
     * @return 转换后的Java对象
     * @throws Exception 转换失败时抛出异常
     */
    public static <T> T jsonToObject(String jsonStr, Class<T> valueType) throws Exception {
        try {
            return objectMapper.readValue(jsonStr, valueType);
        } catch (Exception e) {
            throw new Exception("JSON字符串转对象失败: " + e.getMessage());
        }
    }

    /**
     * 将Java对象转换为JSON字符串
     * @param object 要转换的Java对象
     * @return JSON格式字符串
     * @throws Exception 转换失败时抛出异常
     */
    public static String objectToJson(Object object) throws Exception {
        try {
            return objectMapper.writeValueAsString(object);
        } catch (Exception e) {
            throw new Exception("对象转JSON字符串失败: " + e.getMessage());
        }
    }
}
